import redux from './index';

describe('Redux Functions', () => {
    let listenerCallback: jest.Mock;

    beforeEach(() => {
        listenerCallback = jest.fn();
    });

    afterEach(() => {
        jest.clearAllMocks();
    });

    test('listener should be called on state change', () => {
        redux.listener('test', listenerCallback);

        // Trigger a state change
        redux.create('test', {value: 'newValue'});

        expect(listenerCallback).toHaveBeenCalledTimes(1);
        expect(listenerCallback).toHaveBeenCalledWith({value: 'newValue'});
    });

    test('all should return the entire state', () => {
        const state = redux.all();
        expect(state).toEqual({test: {value: 'newValue'}});
    });

    test('get should return the data by name', () => {
        const data = redux.get('test');
        expect(data).toEqual({value: 'newValue'});
    });

    test('add should create or update the data', () => {
        const initialData = redux.add('test', {value: 'initialValue'});
        expect(initialData).toEqual({value: 'initialValue'});

        const updatedData = redux.add('test', {value: 'updatedValue'});
        expect(updatedData).toEqual({value: 'updatedValue'});
    });

    test('update should dispatch the update action and return the updated data', () => {
        const updatedData = redux.update('test', {value: 'updatedValue1'});
        expect(updatedData).toEqual({value: 'updatedValue1'});
    });

    test('remove should dispatch the remove action', () => {
        redux.remove('test');
        const state = redux.all();
        expect(state).toEqual({});
    });

    test('removeAndInit should dispatch the removeAndInit action', () => {
        redux.create('test', {value: 'valueToRemoveAndInit'}, true);
        redux.update('test', {value: 'updatedValue2'});
        const data = redux.get('test');
        expect(data).toEqual({value: 'updatedValue2'});
        redux.removeAndInit('test');
        const data2 = redux.get('test');
        expect(data2).toEqual({value: 'valueToRemoveAndInit'});
    });
});
